package com.googlecode.grima.service;

import java.util.List;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.googlecode.grima.util.SecurityUtil;

@Service("processService")
public class ProcessService {

	@Autowired
	private RepositoryService repositoryService;

	@Autowired
	private RuntimeService runtimeService;

	@Autowired
	private TaskService taskService;

	public List<ProcessDefinition> getProcessDefinitionList() {
		return repositoryService.createProcessDefinitionQuery().list();
	}

	public void deployProcess(String fileName) {
		repositoryService.createDeployment().addClasspathResource(fileName).deploy();
	}

	public ProcessInstance startProcessInstanceById(String processDefinitionId) {
		ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId);
		return processInstance;
	}

	public List<Task> getPersonalTaskList() {
		String currentUsername = SecurityUtil.getCurrentUsername();
		List<Task> task = taskService.createTaskQuery().taskAssignee(currentUsername).list();
		return task;
	}

	public void startTask(String taskId) {
		String currentUsername = SecurityUtil.getCurrentUsername();
		taskService.claim(taskId, currentUsername);
	}

	public void completeTask(String taskId) {
		taskService.complete(taskId);
	}

	public Task findTaskById(String taskId) {
		TaskQuery query = taskService.createTaskQuery().taskId(taskId);
		Task task = query.singleResult();
		return task;
	}
	
	public ProcessDefinition findProcessDefinitionByKey(String processDefinitionKey) {
		ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
		ProcessDefinition processDefinition = processDefinitionQuery.processDefinitionKey(processDefinitionKey).latestVersion().singleResult();
		return processDefinition;
	}
	
	public ProcessDefinition findProcessDefinitionById(String processDefinitionId) {
		ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
		ProcessDefinition processDefinition = processDefinitionQuery.processDefinitionId(processDefinitionId).singleResult();
		return processDefinition;
	}
	
	public ProcessInstance findProcessInstanceById(String processInstanceId) {
		ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
		ProcessInstance processInstance = processInstanceQuery.processInstanceId(processInstanceId).singleResult();
		return processInstance;
	}
	
	public ProcessInstance getSuperProcessInstance(String processInstanceId){
		ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
		ProcessInstance processInstance = processInstanceQuery.subProcessInstanceId(processInstanceId).singleResult();
		return processInstance;
	}
	
	public List<ProcessInstance> getSubProcessInstances(String processInstanceId){
		ProcessInstanceQuery processInstanceQuery = runtimeService.createProcessInstanceQuery();
		List<ProcessInstance> processInstances = processInstanceQuery.superProcessInstanceId(processInstanceId).list();
		return processInstances;
	}

}
